<template>
  <div class="snake-game">
    <el-card class="game-container">
      <template #header>
        <div class="game-header">
          <span>贪吃蛇游戏</span>
          <el-button type="primary" @click="resetGame">重新开始</el-button>
          <span class="score">分数: {{ gameState.score }}</span>
        </div>
      </template>

      <div class="game-board" ref="gameBoard" @keydown="handleKeyDown" tabindex="0">
        <div v-for="(row, i) in grid" :key="i" class="row">
          <div
              v-for="(cell, j) in row"
              :key="j"
              class="cell"
              :class="{
              'snake-cell': isSnakeCell(i, j),
              'food-cell': isFoodCell(i, j)
            }"
          ></div>
        </div>
      </div>

      <div v-if="gameState.gameOver" class="game-over">
        <h2>游戏结束!</h2>
        <p>最终得分: {{ gameState.score }}</p>
      </div>
    </el-card>

    <template>

    </template>

    <div class="controls">
      <el-row :gutter="16" justify="center">
        <el-col :span="8">
          <el-button @click="changeDirection('UP')" :icon="Top"></el-button>
        </el-col>
      </el-row>
      <div style="margin-top: 15px">
        <el-row :gutter="16">
          <el-col :span="8">
            <el-button @click="changeDirection('LEFT')" :icon="Back"></el-button>
          </el-col>
          <el-col :span="8">
            <el-button @click="changeDirection('DOWN')" :icon="Bottom"></el-button>
          </el-col>
          <el-col :span="8">
            <el-button @click="changeDirection('RIGHT')" :icon="Right"></el-button>
          </el-col>
        </el-row>
      </div>
    </div>
  </div>
</template>

<script>
import {Top,Bottom,Back,Right} from "@element-plus/icons-vue";
import { ref, onMounted, computed } from 'vue';
import axios from 'axios';
import { ElRow ,ElCol, ElButton } from 'element-plus'

export default {
  name: 'SnakeGame',
  computed: {
    Right() {
      return Right
    },
    Back() {
      return Back
    },
    Bottom() {
      return Bottom
    },
    Top() {
      return Top
    }
  },
  setup() {
    const gameState = ref({
      grid: Array(20).fill().map(() => Array(20).fill(0)),
      snake: [],
      food: [],
      direction: 'RIGHT',
      gameOver: false,
      score: 0
    });

    const gameBoard = ref(null);
    const gameInterval = ref(null);
    const GRID_SIZE = 20;

    const grid = computed(() => {
      const grid = Array(GRID_SIZE).fill().map(() => Array(GRID_SIZE).fill(0));

      // 标记蛇身
      gameState.value.snake.forEach(segment => {
        if (segment[0] >= 0 && segment[0] < GRID_SIZE &&
            segment[1] >= 0 && segment[1] < GRID_SIZE) {
          grid[segment[0]][segment[1]] = 1;
        }
      });

      // 标记食物
      if (gameState.value.food && gameState.value.food.length === 2) {
        grid[gameState.value.food[0]][gameState.value.food[1]] = 2;
      }

      return grid;
    });

    const isSnakeCell = (i, j) => {
      return grid.value[i][j] === 1;
    };

    const isFoodCell = (i, j) => {
      return grid.value[i][j] === 2;
    };

    const fetchGameState = async () => {
      try {
        const response = await axios.get('/api/snakeGame/state');
        gameState.value = response.data;
      } catch (error) {
        console.error('Error fetching game state:', error);
      }
    };

    const moveSnake = async () => {
      try {
        const response = await axios.post('/api/snakeGame/move');
        gameState.value = response.data;
      } catch (error) {
        console.error('Error moving snake:', error);
      }
    };

    const changeDirection = async (direction) => {
      try {
        await axios.post('/api/snakeGame/direction', null, {
          params: { direction }
        });
      } catch (error) {
        console.error('Error changing direction:', error);
      }
    };

    const resetGame = async () => {
      try {
        const response = await axios.post('/api/snakeGame/reset');
        gameState.value = response.data;
        startGame();
      } catch (error) {
        console.error('Error resetting game:', error);
      }
    };

    const handleKeyDown = (e) => {
      switch (e.key) {
        case 'ArrowUp':
          changeDirection('UP');
          break;
        case 'ArrowDown':
          changeDirection('DOWN');
          break;
        case 'ArrowLeft':
          changeDirection('LEFT');
          break;
        case 'ArrowRight':
          changeDirection('RIGHT');
          break;
      }
    };

    const startGame = () => {
      if (gameInterval.value) {
        clearInterval(gameInterval.value);
      }

      gameInterval.value = setInterval(() => {
        if (!gameState.value.gameOver) {
          moveSnake();
        } else {
          clearInterval(gameInterval.value);
        }
      }, 200);
    };

    onMounted(() => {
      fetchGameState().then(() => {
        startGame();
        gameBoard.value.focus();
      });
    });

    return {
      gameState,
      grid,
      gameBoard,
      isSnakeCell,
      isFoodCell,
      changeDirection,
      resetGame,
      handleKeyDown
    };
  }
};
</script>

<style scoped>
.snake-game {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 20px;
}

.game-container {
  width: 500px;
  margin-bottom: 20px;
}

.game-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.game-board {
  display: flex;
  flex-direction: column;
  border: 1px solid #ddd;
  outline: none;
}

.row {
  display: flex;
}

.cell {
  width: 20px;
  height: 20px;
  border: 1px solid #eee;
  box-sizing: border-box;
}

.snake-cell {
  background-color: #409EFF;
}

.food-cell {
  background-color: #F56C6C;
  border-radius: 50%;
}

.game-over {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background-color: rgba(255, 255, 255, 0.9);
  padding: 20px;
  border-radius: 5px;
  text-align: center;
}

.controls {
  margin-top: 20px;
}

.score {
  margin-left: 20px;
  font-weight: bold;
}
</style>